//! 网络流抽象trait
//! 
//! 定义与具体网络实现（如Tokio）解耦的网络流接口

use std::io;

/// 网络流抽象trait，避免与tokio等具体实现耦合
pub trait NetworkStream: Send + Sync + std::fmt::Debug + 'static {
    /// 异步读取数据到缓冲区
    /// 返回读取的字节数，0表示连接关闭
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
    
    /// 异步写入数据
    /// 返回写入的字节数
    fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
    
    /// 刷新缓冲区
    fn flush(&mut self) -> io::Result<()>;
    
    /// 检查连接是否仍然有效
    fn is_connected(&self) -> bool;
    
    /// 获取远程地址（用于日志和调试）
    fn remote_addr(&self) -> Option<String>;
    
    /// 优雅关闭连接
    fn shutdown(&mut self) -> io::Result<()>;
}

/// 标准 TCP 流适配器（使用标准库，避免tokio依赖）
#[derive(Debug)]
pub struct TcpStreamAdapter {
    stream: std::net::TcpStream,
    remote_addr: Option<String>,
}

impl TcpStreamAdapter {
    /// 创建新的TCP流适配器
    pub fn new(stream: std::net::TcpStream) -> io::Result<Self> {
        let remote_addr = stream.peer_addr()
            .map(|addr| addr.to_string())
            .ok();
            
        // 设置非阻塞模式（可选）
        stream.set_nonblocking(false)?;
        
        Ok(Self {
            stream,
            remote_addr,
        })
    }
    
    /// 从地址创建TCP连接
    pub fn connect(addr: &str) -> io::Result<Self> {
        let stream = std::net::TcpStream::connect(addr)?;
        Self::new(stream)
    }
}

impl NetworkStream for TcpStreamAdapter {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        use std::io::Read;
        self.stream.read(buf)
    }
    
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        use std::io::Write;
        self.stream.write(buf)
    }
    
    fn flush(&mut self) -> io::Result<()> {
        use std::io::Write;
        self.stream.flush()
    }
    
    fn is_connected(&self) -> bool {
        // 简单检查：尝试获取peer地址
        self.stream.peer_addr().is_ok()
    }
    
    fn remote_addr(&self) -> Option<String> {
        self.remote_addr.clone()
    }
    
    fn shutdown(&mut self) -> io::Result<()> {
        self.stream.shutdown(std::net::Shutdown::Both)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_network_stream_trait() {
        // 测试NetworkStream trait的基本功能
        // 这里使用模拟实现进行测试
        
        #[derive(Debug)]
        struct MockStream {
            data: Vec<u8>,
            pos: usize,
            connected: bool,
        }
        
        impl NetworkStream for MockStream {
            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
                if self.pos >= self.data.len() {
                    return Ok(0);
                }
                
                let to_copy = std::cmp::min(buf.len(), self.data.len() - self.pos);
                buf[..to_copy].copy_from_slice(&self.data[self.pos..self.pos + to_copy]);
                self.pos += to_copy;
                Ok(to_copy)
            }
            
            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
                Ok(buf.len())
            }
            
            fn flush(&mut self) -> io::Result<()> {
                Ok(())
            }
            
            fn is_connected(&self) -> bool {
                self.connected
            }
            
            fn remote_addr(&self) -> Option<String> {
                Some("127.0.0.1:6379".to_string())
            }
            
            fn shutdown(&mut self) -> io::Result<()> {
                self.connected = false;
                Ok(())
            }
        }
        
        let mut stream = MockStream {
            data: b"*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n".to_vec(),
            pos: 0,
            connected: true,
        };
        
        assert!(stream.is_connected());
        assert_eq!(stream.remote_addr(), Some("127.0.0.1:6379".to_string()));
        
        let mut buf = [0u8; 100];
        let n = stream.read(&mut buf).unwrap();
        assert!(n > 0);
    }
}